// Copyright 2022 jeff.li. and/or its affiliates.


/*!
 * \file text_printer.cc
 * \brief Printer to print out the unified IR text format
 *        that can be parsed by a parser.
 */
#include "text_printer.h"

#include <string>

#include <tbir/runtime/registry.h>

namespace tbir::runtime {

    static const char *kSemVer = "0.0.5";

    printer::Doc TextPrinter::PrintMod(const ir::IRModule &mod) {
        Doc doc;
        int counter = 0;
        // type definitions
        for (const auto &kv : mod->type_definitions) {
            if (counter++ != 0) {
                doc << Doc::NewLine();
            }
            doc << ir_text_printer_.Print(kv.second);
            doc << Doc::NewLine();
        }
        // functions
        for (const auto &kv : mod->functions) {
            if (counter++ != 0) {
                doc << Doc::NewLine();
            }
            std::ostringstream os;
            os << "def @" << kv.first->name_hint << " ";
            doc << ir_text_printer_.PrintFunc(Doc::Text(os.str()), kv.second);
            doc << Doc::NewLine();
        }
        return doc;
    }

    static String PrettyPrint(const ObjectRef &node) {
        printer::Doc doc;
        doc << TextPrinter(nullptr, false).PrintFinal(node);
        return doc.str();
    }

    static String AsText(const ObjectRef &node) {
        printer::Doc doc;
        doc << "#[version = \"" << kSemVer << "\"]" << printer::Doc::NewLine();
        runtime::TypedNativeFunction<String(ObjectRef)> ftyped = nullptr;
        doc << TextPrinter(ftyped).PrintFinal(node);
        return doc.str();
    }

    TBIR_REGISTER_GLOBAL("ir.PrettyPrint").set_body_typed(PrettyPrint);

    TBIR_REGISTER_GLOBAL("ir.AsText").set_body_typed(AsText);

}  // namespace tbir::runtime
